using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Data;
//autor: Rosandra
namespace CapaAccesoDatos.Clases
{
    public class ReservacionCAD
    {
        //-------------------------------------------------------------------------------//
        // Propiedades de la Clase.                                                      //
        //-------------------------------------------------------------------------------//
        private int id;
        private int idHorario;
        private int idEstacion;
        private int idUsuario;

        //-------------------------------------------------------------------------------//
        // Accesores publicos de la Clase.                                               //
        //-------------------------------------------------------------------------------//
        public int Id
        {
            get { return this.id; }
        }
        public int IdHorario
        {
            get { return this.idHorario; }
        }
        public int IdEstacion
        {
            get { return this.idEstacion; }
        }
        public int IdUsuario
        {
            get { return this.idUsuario; }
        }

        //-------------------------------------------------------------------------------//
        // Estos son los Constructores de la Clase.                                      //
        //-------------------------------------------------------------------------------//
        private ReservacionCAD(int Id, int IdHorario, int IdEstacion, int IdUsuario)
        {
            this.id = Id;
            this.idHorario = IdHorario;
            this.idEstacion = IdEstacion;
            this.idUsuario = IdUsuario;
        }

        //-------------------------------------------------------------------------------//
        //Metodos de la interface(despreciada a favor de metodos estaticos)              //
        //-------------------------------------------------------------------------------//
        public static void Save(ReservacionCAD reserva)
        {
            String SqlCommand = "INSERT INTO " + Constantes.Tablas.Reservaciones.Nombre + "(" +
                                Constantes.Tablas.Reservaciones.Campo_IdHorario + ", " +
                                Constantes.Tablas.Reservaciones.Campo_IdEstacion + ", " +
                                Constantes.Tablas.Reservaciones.Campo_IdUsuario + ") VALUES (" 
                                + reserva.IdHorario.ToString() + ", " + 
                                reserva.IdEstacion.ToString() + ", " + 
                                reserva.IdUsuario.ToString() + ")";
            //Sentencia:   
            /* INSERT INTO Tabla (Columna1, Columna2...)        
             * VALUES (Registro1, Registro2....);      
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();                
                Tx = Conexion.BeginTransaction();                 
                Comando.Transaction = Tx;           
                Comando.ExecuteNonQuery();       
                Tx.Commit();      
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.Save(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {               
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return;
        }
        public static void Update(ReservacionCAD reserva)
        {
            String SqlCommand = "UPDATE " + Constantes.Tablas.Reservaciones.Nombre + " SET " +
                                Constantes.Tablas.Reservaciones.Campo_IdHorario + "=" + reserva.IdHorario.ToString() + ", " +
                                Constantes.Tablas.Reservaciones.Campo_IdEstacion + "=" + reserva.IdEstacion.ToString() + ", " +
                                Constantes.Tablas.Reservaciones.Campo_IdUsuario + "=" + reserva.IdUsuario.ToString() + 
                                " WHERE " + Constantes.Tablas.Reservaciones.Campo_Id + "=" + reserva.Id.ToString();
            // Sentencia:
            /* UPDATE Tabla SET Columna1 = valor1, Columna2 = valor2 ...
             * WHERE Id = ObjetoId;
             */
            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();               
                Tx = Conexion.BeginTransaction();                 
                Comando.Transaction = Tx;            
                Comando.ExecuteNonQuery();            
                Tx.Commit();     
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.Update(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {            
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return;
        }
        public static void Delete(ReservacionCAD reserva)
        {
            String SqlCommand = "DELETE FROM " + Constantes.Tablas.Reservaciones.Nombre + " WHERE "
                                + Constantes.Tablas.Reservaciones.Campo_Id + "= " + reserva.Id.ToString();

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();              
                Tx = Conexion.BeginTransaction();                
                Comando.Transaction = Tx;        
                Comando.ExecuteNonQuery();             
                Tx.Commit();   
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.Delete(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {            
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return;
        }

        //-------------------------------------------------------------------------------//
        // Estos son los metodos especiales para el uso de la Capa de Lenguaje de Negocios
        //-------------------------------------------------------------------------------//
        public static List<HorarioCAD> GetHorariosDeOcupacion(int IdEstacion)
        {
            List<HorarioCAD> listaHorarios = new List<HorarioCAD>();
            String SqlCommand = "SELECT * FROM " + Constantes.Tablas.Horarios.Nombre +
                                " WHERE " + Constantes.Tablas.Horarios.Campo_Id + " IN "
                                + " (SELECT " + Constantes.Tablas.Reservaciones.Campo_IdHorario
                                + " FROM " + Constantes.Tablas.Reservaciones.Nombre
                                + " WHERE " + Constantes.Tablas.Reservaciones.Campo_IdEstacion
                                + " = " + IdEstacion.ToString() + ")";
            //Sentencia:   
            /* SELECT * FROM Horarios
             * WHERE ID IN 
             * (SELECT ID_Horario FROM Reservaciones
             *  WHERE ID_Estacion = IdEstacion);
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();              
                Tx = Conexion.BeginTransaction();             
                Comando.Transaction = Tx; 
                Comando.ExecuteNonQuery();     
                Cursor = Comando.ExecuteReader();
                while (Cursor.Read())
                {
                    HorarioCAD horario = new HorarioCAD(Convert.ToDateTime(Cursor[Constantes.Tablas.Horarios.Campo_Hora_Inicio]),
                                                        Convert.ToDateTime(Cursor[Constantes.Tablas.Horarios.Campo_Hora_Fin]));
                    listaHorarios.Add(horario);
                }
                Cursor.Close();
                Tx.Commit();                 
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetHorariosDeOcupacion(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {               
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            if (listaHorarios == null)
                return new List<HorarioCAD>();
            else
                return listaHorarios;
        }

        /* GetReservaciones:
         * Este metodo devuelve todas las reservaciones que tenga un usuario en una lista
         */
        public static List<ReservacionCAD> GetReservaciones(int id_Usuario)
        {
            List<ReservacionCAD> listaReservaciones = new List<ReservacionCAD>();
            String SqlCommand = "SELECT * FROM " + Constantes.Tablas.Reservaciones.Nombre +                                
                                " WHERE " + Constantes.Tablas.Reservaciones.Campo_IdUsuario
                                + " = " + id_Usuario.ToString();
            //Sentencia:   
            /* SELECT * FROM Reservaciones
             * WHERE ID_Usuario = id_Usuario;
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();             
                Tx = Conexion.BeginTransaction();                 
                Comando.Transaction = Tx; 
                Comando.ExecuteNonQuery();         
                Cursor = Comando.ExecuteReader();
                while (Cursor.Read())
                {
                    ReservacionCAD reservacion = new ReservacionCAD(Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_Id]),
                                                                        Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdHorario]),
                                                                        Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdEstacion]),
                                                                        Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdUsuario]));
                    listaReservaciones.Add(reservacion);
                }
                Cursor.Close();
                Tx.Commit(); 
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetReservaciones(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {               
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return listaReservaciones;
        }

        /* GetLastReservaciones:
         * Devuelve una lista con las ultimas cantidad reservaciones de un usuario
         */
        public static List<ReservacionCAD> GetLastReservaciones(int id_Usuario, int cantidad)
        {
            List<ReservacionCAD> retorno = null; // la lista que se va a retornar
            List<ReservacionCAD> reservas = null;// esta lista se llenara con todas las reservaciones
            reservas = GetReservaciones(id_Usuario);         // del usuario 
            if (reservas != null)
            {
                for (int cant = 0; cant < cantidad && cant < reservas.Count; cant++)
                {
                    retorno.Add(reservas[cant]);   // se agrega a la lista de retorno la "cant" de reservaciones
                }                                  // que fueron solicitadas en "cantidad". 
            }
            return retorno;
        }

        /* BuscarPorId: 
         * Devuelve una reservacion dado su id.
         */
        public static ReservacionCAD BuscarPorId(int id)
        {
            ReservacionCAD reserva = null;
            String SqlCommand = "SELECT * FROM " + Constantes.Tablas.Reservaciones.Nombre +
                                " WHERE " + Constantes.Tablas.Reservaciones.Campo_Id
                                + " = " + id.ToString();
            //Sentencia:   
            /* SELECT * FROM Reservaciones
             * WHERE ID = id;
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();             
                Tx = Conexion.BeginTransaction();                
                Comando.Transaction = Tx;                        
                Comando.ExecuteNonQuery();              
                Cursor = Comando.ExecuteReader(CommandBehavior.SingleRow);
                while (Cursor.Read())
                {
                    reserva = new ReservacionCAD(Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_Id]),
                                                   Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdHorario]),
                                                   Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdEstacion]),
                                                   Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdUsuario]));
                }
                Cursor.Close();
                Tx.Commit();                   
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.BuscarPorId(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {              
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();                
            }
            if (reserva != null)
            {
                return reserva;
            }
            else
            {
                throw new Exception("Esta Reservacion ha sido cancelada!");
            }

        }

        /* GetReservacionesCount:
         * Dados dos DateTime (que representarian un intervalo de tiempo) 
         * retornar la cantida de Sanciones que se produjeron en el sistema 
         */
        public static int GetReservacionesCount(DateTime TiempoInicio, DateTime TiempoFin)
        {
            int count = 0;
            String SqlCommand = "SELECT COUNT(" + Constantes.Tablas.Reservaciones.Campo_Id 
                                + ") FROM " + Constantes.Tablas.Reservaciones.Nombre +
                                " WHERE " + Constantes.Tablas.Reservaciones.Campo_IdHorario
                                + " IN (SELECT " + Constantes.Tablas.Horarios.Campo_Id + " FROM "
                                + Constantes.Tablas.Horarios.Nombre + " WHERE " 
                                + Constantes.Tablas.Horarios.Campo_Hora_Inicio + " >= '"
                                + TiempoInicio.ToShortDateString() + "' AND "
                                + Constantes.Tablas.Horarios.Campo_Hora_Fin + " <='"
                                + TiempoFin.ToShortDateString() + "')";
            //Sentencia:
            /*
              SELECT COUNT(ID) FROM Reservaciones
              WHERE ID_Horario IN
              (SELECT ID FROM Horarios
				WHERE Hora_Inicio >= TiempoInicio AND
				      Hora_Fin <=  TiempoFin);
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();             
                Tx = Conexion.BeginTransaction();                
                Comando.Transaction = Tx;                        
                Comando.ExecuteNonQuery();              
                Cursor = Comando.ExecuteReader();
                while (Cursor.Read())
                {
                    count = Convert.ToInt32(Cursor[0]);
                }
                Cursor.Close();
                Tx.Commit();                   
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetReservacionesCountOverload(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {              
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();                
            }
            return count;
        }     
        public static int GetCancelacionesCount(DateTime TiempoInicio, DateTime TiempoFin)
        {
            int count = 0;
            String SqlCommand = "SELECT COUNT(" + Constantes.Tablas.Solicitud_Cancelacion.Campo_Id
                                + ") FROM " + Constantes.Tablas.Solicitud_Cancelacion.Nombre +
                                " WHERE " + Constantes.Tablas.Solicitud_Cancelacion.Campo_HoraEjecucion + ">='" + TiempoInicio.ToString() + "'" +
                                " AND " + Constantes.Tablas.Solicitud_Cancelacion.Campo_HoraEjecucion + "<='" + TiempoFin.ToString() + "'";

            //Sentencia:
            /*
              SELECT COUNT(ID) FROM Reservaciones
              WHERE ID_Horario IN
              (SELECT ID FROM Horarios
				WHERE Hora_Inicio >= TiempoInicio AND
				      Hora_Fin <=  TiempoFin);
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Cursor = Comando.ExecuteReader();
                while (Cursor.Read())
                {
                    count = Convert.ToInt32(Cursor[0]);
                }
                Cursor.Close();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetReservacionesCountOverload(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return count;
        }
        

        /* GetReservacionesCount:
         * Esta version devuelve la cantidad total de reservaciones
         */
        public static int GetReservacionesCount()
        {
            int count = 0;
            String SqlCommand = "SELECT COUNT(" + Constantes.Tablas.Reservaciones.Campo_Id
                                + ") FROM " + Constantes.Tablas.Reservaciones.Nombre;
            //Sentencia:   
            /* SELECT COUNT(ID) FROM Reservaciones
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Cursor = Comando.ExecuteReader(CommandBehavior.SingleRow);
                while (Cursor.Read())
                {
                    count = Convert.ToInt32(Cursor[0]);
                }
                Cursor.Close();
                Tx.Commit();                
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetReservacionesCount(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return count;
        }
        public static int GetCancelacionesCount()
        {
            int count = 0;
            String SqlCommand = "SELECT COUNT(" + Constantes.Tablas.Solicitud_Cancelacion.Campo_Id
                                + ") FROM " + Constantes.Tablas.Solicitud_Cancelacion.Nombre;

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Cursor = Comando.ExecuteReader(CommandBehavior.SingleRow);
                while (Cursor.Read())
                {
                    count = Convert.ToInt32(Cursor[0]);
                }
                Cursor.Close();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetCancelacionesCount(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return count;
        }

        public static List<SolicitudCancelacionCAD> GetLastCancelaciones(int UserId, int Cantidad)
        {
            return null;
        }

        public static ReservacionCAD CrearReservacionCAD(int Id, int IdHorario, int IdEstacion, int IdUsuario)
        { 
            return new ReservacionCAD(Id, IdHorario, IdEstacion, IdUsuario);
        }

        public static List<ReservacionCAD> GetReservacionesActivas(int id_Usuario)
        {
            List<ReservacionCAD> listaReservaciones = new List<ReservacionCAD>();
            String SqlCommand = "SELECT * FROM " + Constantes.Tablas.Reservaciones.Nombre +
                                " WHERE " + Constantes.Tablas.Reservaciones.Campo_IdUsuario
                                + " = " + id_Usuario.ToString() + " AND " + Constantes.Tablas.Reservaciones.Campo_IdHorario +
                                " IN (SELECT " + Constantes.Tablas.Horarios.Campo_Id + " FROM " + Constantes.Tablas.Horarios.Nombre +
                                " WHERE " + Constantes.Tablas.Horarios.Campo_Hora_Inicio + " > '" + DateTime.Now.ToShortDateString() + "')";
            //Sentencia:  
            /* SELECT * FROM Reservaciones
                WHERE ID_Usuario = id_usuaro AND ID_Horario IN
                (SELECT ID_Horario FROM Horarios
                WHERE Hora_Inicio > 'datetime.now');
             */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;
            SqlDataReader Cursor = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Cursor = Comando.ExecuteReader();
                while (Cursor.Read())
                {
                    ReservacionCAD reservacion = new ReservacionCAD(Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_Id]),
                                                                        Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdHorario]),
                                                                        Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdEstacion]),
                                                                        Convert.ToInt32(Cursor[Constantes.Tablas.Reservaciones.Campo_IdUsuario]));
                    listaReservaciones.Add(reservacion);
                }
                Cursor.Close();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos.\n " +
                           "FUNCION: ReservacionesCAD.GetReservacionesActivas(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Cursor.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return listaReservaciones;
        }

    }
}
